<template>
  <el-main>
    <el-form :inline="true" :model="searchForm" class="demo-form-inline">
      <el-form-item>
        <el-input v-model="searchForm.search" placeholder="请输入角色名称" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="onSearch">查询</el-button>
        <el-button icon="el-icon-refresh-right" @click="onRefresh">重置</el-button>
        <el-button type="success" icon="el-icon-plus" @click="openEditWindow">新增</el-button>
      </el-form-item>
    </el-form>

    <el-table
      v-loading="tableLoading"
      :style="{height: tableHeight + 'px'}"
      :data="tableData"
      style="width: 100%;margin-bottom: 20px;"
      row-key="id"
      border
    >
      <el-table-column
        prop="id"
        label="角色编号"
        sortable
        width="150"
      />
      <el-table-column
        prop="code"
        label="角色编码"
        sortable
        width="200"
      />
      <el-table-column
        prop="name"
        label="角色名称"
        sortable
        width="200"
      />
      <el-table-column
        prop="remark"
        label="备注"
        sortable
        width="300"
      />
      <el-table-column
        label="操作"
      >
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit-outline" size="small" @click="edit(scope.row.id)">编辑</el-button>
          <el-button type="success" icon="el-icon-setting" size="small" @click="assignRole(scope.row)">分配权限</el-button>
          <el-button type="danger" icon="el-icon-close" size="small" @click="remove(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="block" style="padding-bottom: 20px">
      <el-pagination
        :current-page="searchForm.current"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="searchForm.size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="searchForm.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <SystemDialog
      :title="roleDialog.title"
      :visible="roleDialog.visible"
      :width="roleDialog.width"
      :height="roleDialog.height"
      @onClose="onClose"
      @onConfirm="onConfirm"
    >
      <div slot="content">
        <el-form ref="editRoleForm" :model="editRoleForm" :rules="editRoleRules" label-width="80px" :inline="true" size="small">
          <el-form-item label="角色编码" prop="code">
            <el-input v-model="editRoleForm.code" class="edit-role-input" autocomplete="off" />
          </el-form-item>
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="editRoleForm.name" class="edit-role-input" autocomplete="off" />
          </el-form-item>
          <el-form-item label="备注" prop="remark">
            <el-input
              v-model="editRoleForm.remark"
              type="textarea"
              class="edit-role-input"
              :autosize="{ minRows: 4, maxRows: 4}"
              placeholder="请输入内容"
              :show-word-limit="true"
            />
          </el-form-item>
        </el-form>
      </div>
    </SystemDialog>
    <!-- 分配权限 -->
    <SystemDialog
      :title="assignRoleDialog.title"
      :visible="assignRoleDialog.visible"
      :width="assignRoleDialog.width"
      :height="assignRoleDialog.height"
      @onClose="assignRoleDialogOnClose"
      @onConfirm="assignRoleDialogOnConfirm"
    >
      <div slot="content">
        <el-tree
          ref="assignRoleTree"
          v-loading="assignPermissionsLoading"
          :data="assignRoleTree"
          show-checkbox
          node-key="id"
          :props="defaultProps"
          empty-text="暂无数据"
          :highlight-current="true"
          default-expand-all
        />
      </div>
    </SystemDialog>
  </el-main>
</template>
<script>
import { deleteRole, getAssignPermissionsTree, getRoleById, getRoles, saveRole, saveRolePermissions } from '@/api/role'
import SystemDialog from '@/components/system/SystemDialog.vue'
import myConfirm from '@/utils/myconfirm'
import leafUtils from '@/utils/leaf'

export default {
  components: { SystemDialog },
  data() {
    return {
      assignPermissionsLoading: false,
      tableLoading: false,
      tableHeight: 0,
      searchForm: {
        current: 1
      },
      tableData: [{
        id: 1,
        code: 'admin',
        name: '管理员'
      }],
      editRoleForm: {},
      editRoleRules: {
        code: [{ required: true, trigger: 'blur', message: '请输入角色编码' }],
        name: [{ required: true, trigger: 'blur', message: '请输入角色名称' }]
      },
      roleDialog: {
        title: '',
        visible: false,
        width: 500, // 窗口宽度
        height: 220 // 窗口高度
      },
      assignRoleDialog: {
        title: '',
        visible: false,
        width: 500, // 窗口宽度
        height: 500 // 窗口高度
      },
      assignRoleTree: [],
      currentRoleId: '',
      defaultProps: {
        children: 'children',
        label: 'label'
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      // 容器高度
      this.tableHeight = window.innerHeight - 230
    })
  },
  created() {
    this.getRoles()
  },
  methods: {
    getRoles() {
      this.tableLoading = true
      getRoles(this.searchForm).then(res => {
        this.tableData = res.data.records
        this.searchForm.currentPage = res.data.currentPage
        this.searchForm.size = res.data.size
        this.searchForm.total = res.data.total
        this.tableLoading = false
      })
    },
    handleSizeChange(val) {
      this.searchForm.size = val
      this.getRoles()
    },
    handleCurrentChange(val) {
      this.searchForm.current = val
      this.getRoles()
    },
    edit(id) {
      getRoleById(id).then(res => {
        this.editRoleForm = res.data
        this.openEditWindow()
      })
    },
    assignRole(role) {
      this.currentRoleId = role.id
      this.assignPermissionsLoading = true
      getAssignPermissionsTree(role.id).then(res => {
        console.log(res.data)
        const { permissionList, checkList } = res.data
        // 判断当前菜单是否是最后一级
        const { setLeaf } = leafUtils()
        // 设置权限菜单列表
        const permissions = setLeaf(permissionList)
        // 设置树节点数据
        this.assignRoleTree = permissions
        // 将回调延迟到下一次DOM更新循环之后执行，在修改数据之后立即调用该方法，然后等DOM更新
        this.$nextTick(() => {
          const nodes = this.$refs.assignRoleTree.children
          // 设置子节点
          this.setChild(nodes, checkList)
        })
      })
      this.openAssignWindow(role)
    },
    // 设置子节点
    setChild(childNodes, checkList) {
      if (childNodes && childNodes.length > 0) {
        for (let i = 0; i < childNodes.length; i++) {
          // 根据data或key获取树组件中的node节点
          const node = this.$refs.assignRoleTree.getNode(childNodes[i])
          // 判断是否已经拥有对应的角色数据
          if (checkList && checkList.length > 0) {
            for (let j = 0; j < checkList.length; j++) {
              // 判断权限编号是否相等
              if (childNodes[i].id === checkList[j]) {
                // 判断节点状态，如果当前节点是展开的，则将树节点选中
                if (childNodes[i].open) {
                  this.$refs.assignRoleTree.setChecked(node, true)
                  break
                }
              }
            }
          }
          // 如果存在子节点，则递归选中
          if (childNodes[i].children) {
            this.setChild(childNodes[i].children, checkList)
          }
        }
      }
    },
    openAssignWindow(role) {
      this.assignRoleDialog.title = '分配' + role.name + '权限'
      this.assignRoleDialog.visible = true
      this.assignPermissionsLoading = false
    },
    onSearch() {
      this.getRoles()
    },
    onRefresh() {
      this.searchForm.search = ''
      this.getRoles()
    },
    openEditWindow() {
      this.roleDialog.title = '编辑'
      this.roleDialog.visible = true
    },
    clearEditWindow() {
      this.roleDialog.visible = false
      this.editRoleForm = {}
      this.$refs['editRoleForm'].resetFields()
    },
    onConfirm() {
      this.$refs.editRoleForm.validate(valid => {
        if (valid) {
          saveRole(this.editRoleForm).then(res => {
            this.clearEditWindow()
            this.getRoles()
          })
        }
      })
    },
    onClose() {
      this.clearEditWindow()
    },
    async remove(id) {
      const result = await myConfirm('确定删除吗')
      if (result) {
        deleteRole(id).then(res => {
          this.getRoles()
        })
      }
    },
    assignRoleDialogOnClose() {
      this.assignRoleDialog.visible = false
      this.currentRoleId = ''
    },
    assignRoleDialogOnConfirm() {
      // 获取选中的树节点的值
      const ids = this.$refs.assignRoleTree.getCheckedKeys()
      // 获取选中的树节点父节点的值
      const parentIds = this.$refs.assignRoleTree.getHalfCheckedKeys()
      // 组装选中节点的ID数据
      const permissionIds = ids.concat(parentIds)
      if (permissionIds.length > 0) {
        const data = {
          permissionIds: permissionIds,
          roleId: this.currentRoleId
        }
        saveRolePermissions(data).then(res => {
          if (res.code === 200) {
            this.$message.success(res.data)
          } else {
            this.$message.error(res.message)
          }
        })
      } else {
        this.$message.info('请选择权限信息')
      }
    }
  }
}
</script>

<style scoped lang="scss">
.edit-role-input {
  width: 300px;
}
</style>
